package cn.xiangxu.webfulx_structure.controller;

import cn.xiangxu.webfulx_structure.domain.StudentDO;
import cn.xiangxu.webfulx_structure.repository.StudentReporitory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.concurrent.TimeUnit;

/**
 * @author 王杨帅
 * @create 2018-08-07 21:25
 * @desc 学生控制层
 **/
@RestController
@RequestMapping(value = "/stu")
@Slf4j
public class StudentController {

    private final StudentReporitory studentReporitory;

    public StudentController(StudentReporitory studentReporitory) {
        this.studentReporitory = studentReporitory;
    }

    /**
     * 查询用户
     * @return
     */
    @GetMapping(value = "/queryAll")
    public Flux<StudentDO> queryAll() {
        return studentReporitory.findAll();
    }

    /**
     * 插叙用户【流式返回】
     * @return
     */
    @GetMapping(value = "/queryAll/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<StudentDO> queryAllStream() {
        return studentReporitory.findAll();
    }

    /**
     * 新增学生
     * @param studentDO
     * @return
     */
    @PostMapping(value = "/")
    public Mono<StudentDO> create(
            @RequestBody StudentDO studentDO
    ) {
        if (StringUtils.isEmpty(studentDO.getId())) {
            log.info(this.getClass().getName() + " -【create】- 获取到的参数信息为：" + studentDO);
            return studentReporitory.save(studentDO);
        } else {
            log.error(this.getClass().getName() + "-【create】- 新增学生时不能传入ID信息");
            throw new RuntimeException("新增学生时不能传入ID信息");
        }
    }

    /**
     * 创建学生【流式返回】
     * @param studentDO
     * @return
     */
    @PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Mono<StudentDO> create02(
            @RequestBody StudentDO studentDO
    ) {
        if (StringUtils.isEmpty(studentDO.getId())) {
            log.info(this.getClass().getName() + " -【create】- 获取到的参数信息为：" + studentDO);
            return studentReporitory.save(studentDO);
        } else {
            log.error(this.getClass().getName() + "-【create】- 新增学生时不能传入ID信息");
            throw new RuntimeException("新增学生时不能传入ID信息");
        }
    }

    /**
     * 根据ID删除对象
     * @param id
     * @return
     */
    @DeleteMapping(value = "/{id}")
    public Mono<ResponseEntity<Void>> delete(
            @PathVariable(value = "id") String id
    ) {
        log.info(id);
        if(id.chars().toArray().length == 24) {
            return studentReporitory.findById(id)
                .flatMap(
                        stu -> studentReporitory.delete(stu)
                                    .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))
                )
                .defaultIfEmpty(new ResponseEntity<Void>(HttpStatus.NOT_FOUND));
        } else {
            log.error("【delete】-参数错误");
            throw new RuntimeException("参数错误");
        }

    }

    @PutMapping(value = "/")
    public Mono<ResponseEntity> update(
            @RequestBody StudentDO studentDO
    ) {
        log.info("修改数据：" + studentDO);
        return studentReporitory.findById(studentDO.getId())
                .flatMap(
                        stu -> {
                            log.info("数据存在");
                            BeanUtils.copyProperties(studentDO, stu);
                            return studentReporitory.save(stu);
                        }
                )
                .map(stu -> new ResponseEntity(stu, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @GetMapping(value = "/queryById/{id}")
    public Mono<ResponseEntity<StudentDO>> queryById(
            @PathVariable("id") String id
    ) {
        log.info("从前端获取到的ID信息为：" + id);
        return studentReporitory.findById(id)
                .map(stu -> new ResponseEntity<StudentDO>(stu, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

}

